from rest_framework import serializers
from system.models import Notice, UserNotice, User
from django.utils import timezone
import jwt
from django.conf import settings


class NoticePageSerializer(serializers.ModelSerializer):
    """通知公告分页列表序列化器"""
    publishStatus = serializers.IntegerField(source='publish_status')
    publishTime = serializers.DateTimeField(source='publish_time', format='%Y-%m-%d %H:%M', required=False, allow_null=True)
    createTime = serializers.DateTimeField(source='create_time', format='%Y-%m-%d %H:%M')
    revokeTime = serializers.DateTimeField(source='revoke_time', format='%Y-%m-%d %H:%M', required=False, allow_null=True)
    targetType = serializers.IntegerField(source='target_type')
    publisherName = serializers.SerializerMethodField()
    
    class Meta:
        model = Notice
        fields = ['id', 'title', 'publishStatus', 'type', 'publisherName', 'level', 
                 'publishTime', 'targetType', 'createTime', 'revokeTime']
    
    def get_publisherName(self, obj):
        """获取发布人名称"""
        if obj.publisher:
            try:
                publisher = User.objects.get(id=obj.publisher)
                return publisher.nickname or publisher.username
            except User.DoesNotExist:
                return None
        return None


class NoticeDetailSerializer(serializers.ModelSerializer):
    """通知公告详情序列化器"""
    publishStatus = serializers.IntegerField(source='publish_status')
    publishTime = serializers.DateTimeField(source='publish_time', format='%Y-%m-%d %H:%M:%S', required=False, allow_null=True)
    publisherName = serializers.SerializerMethodField()
    
    class Meta:
        model = Notice
        fields = ['id', 'title', 'content', 'type', 'publisherName', 'level', 'publishStatus', 'publishTime']
    
    def get_publisherName(self, obj):
        """获取发布人名称"""
        if obj.publisher:
            try:
                publisher = User.objects.get(id=obj.publisher)
                return publisher.nickname or publisher.username
            except User.DoesNotExist:
                return None
        return None


class NoticeFormSerializer(serializers.ModelSerializer):
    """通知公告表单序列化器"""
    targetType = serializers.IntegerField(source='target_type')
    targetUserIds = serializers.SerializerMethodField()
    
    class Meta:
        model = Notice
        fields = ['id', 'title', 'content', 'type', 'level', 'targetType', 'targetUserIds']
    
    def get_targetUserIds(self, obj):
        """获取目标用户ID列表"""
        if obj.target_type == 2 and obj.target_user_ids:
            return obj.target_user_ids.split(',')
        return []


class NoticeUpdateSerializer(serializers.ModelSerializer):
    """通知公告更新序列化器"""
    targetUserIds = serializers.ListField(
        child=serializers.CharField(),
        required=False,
        help_text="目标用户ID列表"
    )
    targetType = serializers.IntegerField(source='target_type')
    
    class Meta:
        model = Notice
        fields = ['id', 'title', 'content', 'type', 'level', 'targetType', 'targetUserIds']
        extra_kwargs = {
            'id': {'read_only': True},
            'title': {'required': True, 'max_length': 50},
            'content': {'required': True},
            'type': {'required': True},
            'level': {'required': True},
        }
    
    def to_internal_value(self, data):
        """
        转换前端数据格式为后端模型格式
        """
        # 检查前端是否传入了targetType和targetUserIds
        if 'targetType' in data and not 'target_type' in data:
            data = data.copy()  # 避免修改原始数据
            data['target_type'] = data['targetType']
        
        # 将ListField值转换为Python List
        if 'targetUserIds' in data and isinstance(data['targetUserIds'], str):
            data = data.copy()  # 避免修改原始数据
            try:
                import json
                data['targetUserIds'] = json.loads(data['targetUserIds'])
            except json.JSONDecodeError:
                # 如果不是JSON格式，可能是逗号分隔的字符串
                data['targetUserIds'] = [item.strip() for item in data['targetUserIds'].split(',') if item.strip()]
        
        # 调用父类方法继续处理
        return super().to_internal_value(data)
    
    def validate(self, attrs):
        """验证通知数据"""
        target_type = attrs.get('target_type')
        target_user_ids = attrs.get('targetUserIds', [])
        
        # 验证目标类型与目标用户ID列表的一致性
        if target_type == 2 and not target_user_ids:  # 指定用户但未提供用户ID
            raise serializers.ValidationError("当目标类型为'指定用户'时，必须提供目标用户ID列表")
            
        # 验证目标用户是否存在
        if target_type == 2 and target_user_ids:
            # 验证用户ID是否存在
            existing_user_ids = set(User.objects.filter(
                id__in=target_user_ids,
                is_deleted=0,
                status=1
            ).values_list('id', flat=True))
            
            # 找出不存在的用户ID
            non_existing_user_ids = set(int(uid) for uid in target_user_ids) - existing_user_ids
            if non_existing_user_ids:
                raise serializers.ValidationError(
                    f"以下用户ID不存在或已被禁用：{', '.join(map(str, non_existing_user_ids))}"
                )
        
        return attrs
    
    def update(self, instance, validated_data):
        """更新通知公告"""
        # 提取targetUserIds字段，不属于Notice模型
        target_user_ids = validated_data.pop('targetUserIds', [])
        
        # 如果是指定用户类型，处理目标用户ID列表
        if validated_data.get('target_type') == 2 and target_user_ids:
            # 将用户ID列表转换为逗号分隔的字符串
            validated_data['target_user_ids'] = ','.join(target_user_ids)
        elif validated_data.get('target_type') == 1:
            # 全体用户类型，清空目标用户ID列表
            validated_data['target_user_ids'] = None
        
        # 设置更新时间和更新人ID
        user_id = self.context.get('user_id')
        if user_id:
            validated_data['update_by'] = user_id
        validated_data['update_time'] = timezone.now()
        
        # 如果通知已发布，不允许修改某些字段
        if instance.publish_status == 1:  # 已发布
            # 移除不允许修改的字段
            for field in ['target_type', 'target_user_ids']:
                if field in validated_data:
                    validated_data.pop(field)
        
        # 更新通知公告
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        
        return instance


class NoticeCreateSerializer(serializers.ModelSerializer):
    """通知公告创建序列化器"""
    targetUserIds = serializers.ListField(
        child=serializers.CharField(),
        required=False,
        help_text="目标用户ID列表"
    )
    targetType = serializers.IntegerField(source='target_type')
    
    class Meta:
        model = Notice
        fields = ['id', 'title', 'content', 'type', 'level', 'targetType', 'targetUserIds']
        extra_kwargs = {
            'id': {'read_only': True},
            'title': {'required': True, 'max_length': 50},
            'content': {'required': True},
            'type': {'required': True},
            'level': {'required': True},
        }
    
    def to_internal_value(self, data):
        """
        转换前端数据格式为后端模型格式
        """
        # 检查前端是否传入了targetType和targetUserIds
        if 'targetType' in data and not 'target_type' in data:
            data = data.copy()  # 避免修改原始数据
            data['target_type'] = data['targetType']
        
        # 将ListField值转换为Python List
        if 'targetUserIds' in data and isinstance(data['targetUserIds'], str):
            data = data.copy()  # 避免修改原始数据
            try:
                import json
                data['targetUserIds'] = json.loads(data['targetUserIds'])
            except json.JSONDecodeError:
                # 如果不是JSON格式，可能是逗号分隔的字符串
                data['targetUserIds'] = [item.strip() for item in data['targetUserIds'].split(',') if item.strip()]
        
        # 调用父类方法继续处理
        return super().to_internal_value(data)
    
    def to_representation(self, instance):
        """
        将模型实例转换为API响应格式
        """
        # 调用父类方法
        data = super().to_representation(instance)
        
        # 将下划线字段名转换为驼峰命名
        if 'target_type' in data:
            data['targetType'] = data.pop('target_type')
        
        # 处理目标用户ID列表
        if hasattr(instance, 'target_user_ids') and instance.target_user_ids:
            data['targetUserIds'] = instance.target_user_ids.split(',')
        else:
            data['targetUserIds'] = []
        
        return data
    
    def validate(self, attrs):
        """验证通知数据"""
        target_type = attrs.get('target_type')
        target_user_ids = attrs.get('targetUserIds', [])
        
        # 验证目标类型与目标用户ID列表的一致性
        if target_type == 2 and not target_user_ids:  # 指定用户但未提供用户ID
            raise serializers.ValidationError("当目标类型为'指定用户'时，必须提供目标用户ID列表")
            
        # 验证目标用户是否存在
        if target_type == 2 and target_user_ids:
            # 验证用户ID是否存在
            existing_user_ids = set(User.objects.filter(
                id__in=target_user_ids,
                is_deleted=0,
                status=1
            ).values_list('id', flat=True))
            
            # 找出不存在的用户ID
            non_existing_user_ids = set(int(uid) for uid in target_user_ids) - existing_user_ids
            if non_existing_user_ids:
                raise serializers.ValidationError(
                    f"以下用户ID不存在或已被禁用：{', '.join(map(str, non_existing_user_ids))}"
                )
        
        return attrs
    
    def create(self, validated_data):
        """创建通知公告"""
        # 提取targetUserIds字段，不属于Notice模型
        target_user_ids = validated_data.pop('targetUserIds', [])
        
        # 如果是指定用户类型，处理目标用户ID列表
        if validated_data.get('target_type') == 2 and target_user_ids:
            # 将用户ID列表转换为逗号分隔的字符串
            validated_data['target_user_ids'] = ','.join(target_user_ids)
        
        # 设置创建时间
        validated_data['create_time'] = timezone.now()
        
        # 设置创建人ID
        user_id = self.context.get('user_id')
        if user_id:
            validated_data['create_by'] = user_id
        
        # 默认设置为未发布状态
        validated_data['publish_status'] = 0
        
        # 创建通知公告
        notice = Notice.objects.create(**validated_data)
        
        return notice


class NoticeMyPageSerializer(serializers.ModelSerializer):
    """用户通知公告分页列表序列化器"""
    id = serializers.IntegerField(source='notice.id')
    title = serializers.CharField(source='notice.title')
    type = serializers.IntegerField(source='notice.type')
    level = serializers.CharField(source='notice.level')
    publisherName = serializers.SerializerMethodField()
    publishTime = serializers.SerializerMethodField()
    isRead = serializers.IntegerField(source='is_read')
    
    class Meta:
        model = UserNotice
        fields = ['id', 'title', 'type', 'level', 'publisherName', 'publishTime', 'isRead']
    
    def get_publisherName(self, obj):
        """获取发布人名称"""
        publisher_id = obj.notice.publisher
        if publisher_id:
            try:
                user = User.objects.get(id=publisher_id)
                return user.nickname or user.username
            except User.DoesNotExist:
                return "未知用户"
        return "系统"
    
    def get_publishTime(self, obj):
        """格式化发布时间"""
        if obj.notice.publish_time:
            return obj.notice.publish_time.strftime('%Y-%m-%d %H:%M')
        return None
